#pragma once
#include "FoundationStruct.h"
#include "BoundBox.h"

/*
 * Set up the 8 corners of each voxel like this:
 * Very important that this is set up the same way as the cube edges
 *
 *  y         z
 *  ^        /
 *  |
 *    6----7
 *   /|   /|
 *  4----5 |
 *  | 2--|-3
 *  |/   |/
 *  0----1   --> x
 *
 */

namespace mini
{
	struct Voxel
	{
		int vertexIndex;
		CPoint3F vertexPosition;
		bool isOnSurface;
		int voxelEdgeMask;
		int cornerMask;
	};

	struct sample 
	{
		CPoint3F point;
		float value;
	};


	class CSurfaceNets
	{
	public:
		CSurfaceNets();
		~CSurfaceNets();

	public:
		// how farm from the surface we want to create our mesh
		float threshold = 0.25f;
		// the resolution
		float samplesPerMeter = 1.0f;
		CPoint3F sampleResolution();
		void GenerateIntersectionTable();
		void GenerateCubeEdgesTable();
		void Awake();
		void runSurfaceNets();

	private:
		CPoint3F GetWorldSpaceSamplePosition(int x, int y, int z);
		
	private:
		std::vector<int> buffer;
		CBoundBox	sampleSpace;

		// create an array of voxels that'll fill our sample space
		std::vector< std::vector< std::vector<Voxel>>> voxels;
		std::list<CPoint3F> vertices;
		std::list<CPoint3F> newVertices;
		std::list<int> triangles;

		// Define the edge table and cube edges with a set size
		std::vector<int> edgeTable;
		std::vector<int> cubeEdges;

		std::vector<CPoint3F> voxelCornerOffsets;

	};
}